home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / Amiga_Mail_Vol2 / Archives / Plain / jf91 / extscreen.txt < prev    next >
Encoding:
Text File  |  1991-04-15  |  19.2 KB  |  476 lines

  1. (c)  Copyright 1991 Commodore-Amiga, Inc.   All rights reserved.
  2. The information contained herein is subject to change without notice,
  3. and is provided "as is" without warranty of any kind, either expressed
  4. or implied.  The entire risk as to the use of this information is
  5. assumed by the user.
  6.  
  7.  
  8.  
  9. Opening Screens and Windows on Any Amiga
  10.  
  11.  
  12. by Ewout Walraven
  13.  
  14. The release 2.0 intuition.library has a multitude of new display
  15. possibilities at its disposal that developers can use to improve their
  16. software.  Many products can benefit from the flexibility that higher
  17. display resolutions and larger display areas offer and from the
  18. polished user interface available with the ``New Look'' in release
  19. 2.0.  Because backward compatibility with 1.3 is important to many
  20. developers, these new features should be used in a way that will work
  21. with older systems.
  22.  
  23. This article shows how to take advantage of the display resources
  24. available to Intuition under any Amiga system.  This article assumes
  25. the reader has some knowledge of release 2.0 (V36) screens and
  26. windows.  For more information, see the article ``An Introduction to
  27. V36 Screens and Windows'' from the September/October 1990 issue of
  28. Amiga Mail.
  29.  
  30.  
  31. Opening Full Size Screens
  32.  
  33. Under pre-V36 versions of the operating system, a method commonly used
  34. to open a screen according to user preference was to ``clone'' the
  35. Workbench screen (to create a screen with the same resolution and view
  36. mode as the Workbench screen).  Normally, applications called the
  37. Intuition function GetScreenData() to learn the Workbench screen's
  38. resolution and display mode.
  39.  
  40. Programmers should no longer rely on GetScreenData() to return the
  41. actual resolution and display mode under release 2.0.  When asked
  42. about the Workbench screen, the V2.0 GetScreenData() returns the video
  43. mode of a Hires screen, or, if the screen is interlaced, a Hires
  44. interlaced screen.  The dimensions GetScreenData() returns will be the
  45. lesser of either the OSCAN_TEXT dimensions or the actual Workbench
  46. screen dimensions.  This change to GetScreenData() prevents some
  47. programs developed for 1.3 from opening full size screens and windows
  48. under 2.0.  The change had to be made to avoid confusing programs that
  49. couldn't handle the higher resolutions and new display modes that are
  50. available in release 2.0.  For example, when GetScreenData() is called
  51. on a system using a SuperHires interlaced Workbench screen, it returns
  52. the dimensions and view mode of a Hires interlaced screen.  If
  53. GetScreenData() had supplied the actual resolution instead, a program
  54. that assumed the resolution could not be greater than 640x400 could be
  55. severely crippled.  The exception to this rule is a system running in
  56. one of the A2024 (or Hedley Hires) modes.  To remain compatible with
  57. the V35 version of GetScreenData(), the release 2.0 version returns
  58. the correct dimensions of a screen in A2024 mode.
  59.  
  60. Another method previously used to get information about the Workbench
  61. screen was to look at the GfxBase->NormalDisplayRows and
  62. GfxBase->NormalDisplayColumns fields.  As with GetScreenData(), these
  63. fields contain the dimensions of a text overscan Hires (or Hires
  64. interlace) screen.  Obviously, these fields should no longer be used
  65. to obtain the actual dimensions of the Workbench screen.
  66.  
  67. To clone the Workbench screen under 2.0, lock the Workbench screen,
  68. get the screen's display mode ID, and get the necessary display
  69. information.  The article ``An Introduction to V36 Screens and
  70. Windows'' from the September/October 1990 issue of Amiga Mail contains
  71. the example CloneWB.c which illustrates cloning the Workbench screen
  72. under release 2.0.  Any application that wants to clone the Workbench
  73. screen should be prepared to handle any type of screen, because the
  74. user can change the Workbench screen to any type of screen they
  75. desire.
  76.  
  77.  
  78. PAL or NTSC?
  79.  
  80. Some programs need to determine if the Workbench screen is in PAL or
  81. NTSC mode.  Before release 2.0, it was impossible for the system to
  82. switch between NTSC and PAL.  The PAL/NTSC state in which the machine
  83. booted dictated the mode of its displays.  Pre-V36 systems could
  84. determine the PAL/NTSC state of the machine by examining a bit the in
  85. GfxBase->DisplayFlags field, which is set at boot time under all
  86. versions of the OS.
  87.  
  88. Thanks to the ECS and the new system software, PAL and NTSC display
  89. resolutions can coexist, which obsoletes examining
  90. GfxBase->DisplayFlags to determine the PAL/NTSC state of a particular
  91. system.  Release 2.0 ignores the PAL/NTSC flag after it sets the flag
  92. at boot time.  This means that under 2.0, if the system boots as NTSC,
  93. it is not possible to open a PAL screen in a way that will work
  94. correctly with release 1.3.
  95.  
  96. To respect the user setup of the Workbench rather than the default
  97. video mode, a program should use the V36 graphics.library and
  98. intuition.library functions to determine the display mode ID of the
  99. Workbench screen.  Using that ID, an application can open a screen or
  100. find more information about the properties of the Workbench screen.
  101. The extscreen.c example at the end of this article shows how to check
  102. for a PAL mode screen under any version of the operating system.
  103.  
  104.  
  105. Opening Full Sized Windows
  106.  
  107. Because there is no guarantee that GetScreenData() will return the
  108. correct screen resolution, programs can't use it to obtain the
  109. dimensions needed to open a full sized window.  To get the correct
  110. screen resolution of the Workbench screen, programs have to examine
  111. the Height and Width fields of the Screen structure returned by
  112. LockPubScreen().
  113.  
  114. To make supporting new and old versions of the operating system
  115. easier, Intuition V36 offers a way to open screens and windows that is
  116. compatible with previous versions of the Amiga OS.  Instead of
  117. requiring the use of new functions to open V36 specific screens and
  118. windows, the OpenWindow() and OpenScreen() functions each accept an
  119. extended structure, ExtNewWindow and ExtNewScreen, respectively.
  120. These structures allow the programmer to pass tags to the V36
  121. OpenScreen() and OpenWindow() functions while remaining compatible
  122. with older versions of these functions.  Older versions of Intuition
  123. ignore the excess baggage at the end of the structure where the tags
  124. are kept.  These tags are partially used in V35 (a 1.3 release) to
  125. support the A2024 modes.  Note that the ExtNewScreen and ExtNewWindow
  126. structures may be extended in the future, so programs must not assume
  127. their size is static.
  128.  
  129. To use the ``New Look'', pass the SA_Pens tag and a pen array in
  130. ExtNewScreen.  Using the New Look requires a little bit more
  131. responsibility from an application.  Programs that aren't careful can
  132. experience problems with the layout of graphics and gadgets in New
  133. Look windows and screens.  For example, a lot of programs made
  134. assumptions about the height of a window's title bar.  Under 1.3, this
  135. didn't present much of a problem because the title bar height didn't
  136. normally change.  Under 2.0, the user can choose system fonts, varying
  137. the size of the title bar.  Graphics and gadgets rendered into the
  138. application's window can write over the title bar if the application
  139. isn't careful.
  140.  
  141. The example at the end of this article, extscreen.c, illustrates how
  142. to open a screen and window under release 2.0, using 2.0 specific
  143. features if they are available, while staying compatible with older
  144. versions of the operating system.  This example will open a screen in
  145. A2024 mode (under V37, V36, or V35) if the resources are available.
  146.  
  147.  
  148.  
  149. /*
  150.  * extscreen.c - Usage of NS_EXTENDED & NW_EXTENDED.
  151.  *
  152.  * Compiled with SAS C 5.10:  lc -cfist -v -L extscreen.c
  153.  */
  154.  
  155. #include <intuition/intuition.h>
  156. #include <graphics/gfxbase.h>
  157. #include <graphics/displayinfo.h>
  158. #include <intuition/screens.h>
  159.  
  160. #include <clib/exec_protos.h>
  161. #include <clib/intuition_protos.h>
  162. #include <clib/graphics_protos.h>
  163.  
  164. #include <stdio.h>
  165. #include <stdlib.h>
  166.  
  167.  
  168. struct IntuitionBase *IntuitionBase;
  169. struct GfxBase *GfxBase;
  170. extern struct ExecBase *SysBase;
  171.  
  172.  
  173. /* To get that New Look we'll use Workbench compatible pen numbers.
  174.  * The end of the pen array is indicated with ~0.
  175.  * Note that the screen depth should comply with the pen numbers used.
  176.  * I.e. specifying pen number 3 on a one bitplane screen will obviously
  177.  * not give the desired effect.
  178.  * A description of the pen array can be found in intuition/screens.h.
  179.  */
  180.  
  181. static UWORD    dri_Pens[] =
  182. { 0, 1, 1, 2, 1, 3, 1, 0, 3, ~0};
  183.  
  184. /* zoom/zip/zap/zop array to illustrate NW_EXTENDED */
  185. static UWORD    zoomdata[] =
  186. { 30, 30, 200, 100};
  187.  
  188. /* Old style requester to be compatible with < V36 */
  189. struct IntuiText reqtext[] = {
  190.     { 0,1, JAM1, 10,10, NULL, NULL, NULL},
  191.     { 0,1, JAM1, 6,3, NULL, "Continue", NULL},
  192. };
  193.  
  194. /* local protos */
  195. void            main(void);
  196. BOOL CheckPAL(STRPTR screenname);
  197.  
  198. void main(void)
  199. {
  200.     struct ExtNewScreen xnewscreen;
  201.     struct ExtNewWindow xnewwindow;
  202.     struct Screen  *screen;
  203.     struct Window  *window;
  204.     struct IntuiMessage *msg;
  205.     struct DisplayInfo displayinfo;
  206.     struct TagItem  taglist[3];
  207.     BOOL OpenA2024 = FALSE;
  208.     BOOL IsV36 = FALSE;
  209.     BOOL IsPAL;
  210.  
  211.     if (IntuitionBase = OpenLibrary("intuition.library", 33)) 
  212.     {
  213.         if (GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 33)) 
  214.         {
  215.  
  216.             /* V36 check if a 10 Hz A2024 screen can be opened. If this has to be
  217.              * done in V35 (Jumpstart), start by checking the library version
  218.              * ofcourse. Next simply open the screen with A2024 parameters. If this
  219.              * fails there are a couple of possibilities. The system may have run
  220.              * out of memory or even though the user is running V35 s/he hasn't set
  221.              * up Hedley mode. Logical step in case of failure is to try again with
  222.              * regular parameters. Depending on the nature of the program, this could
  223.              * be done everytime the program starts, or according to some kind of
  224.              * user preferences setting.
  225.              */
  226.  
  227.  
  228.             /* Check for V36>. If present check Hedley (A2024) availability */
  229.             if (GfxBase->LibNode.lib_Version >= 36) 
  230.             {
  231.                 IsV36 = TRUE;
  232.                 /* Use GetDisplayInfoData() with the DTAG_DISP to get the display info,
  233.                  * containing availability. Note that availability means that the user
  234.                  * admonitor'ed A2024, not necessarily that there is a physical A2024
  235.                  * out there.
  236.                  */
  237.                 if(GetDisplayInfoData(NULL, (UBYTE *)&displayinfo,
  238.                     sizeof(struct DisplayInfo), DTAG_DISP, A2024TENHERTZ_KEY))
  239.                     if (displayinfo.NotAvailable == 0)
  240.                         OpenA2024 = TRUE;
  241.             } 
  242.             else 
  243.             {
  244.                 /* Check if V35. If it is indicate I want the  tags added to open a
  245.                  * A2024 screen. Note that this still doesn't mean I can actually open
  246.                  * in Hedley mode.
  247.                  */
  248.                 if (GfxBase->LibNode.lib_Version == 35)
  249.                     OpenA2024 = TRUE;
  250.             }
  251.  
  252.             /* Use a separate CheckPAL() function to see if how the use has set up
  253.              * the system.
  254.              */
  255.             IsPAL = CheckPAL("Workbench");
  256.  
  257.             /* Build taglist, this is completely ignored in V33/V34 and V35 doesn't
  258.              * recognize tags other than those A2024 ones.
  259.              */
  260.  
  261.             /* Pass the A2024 tags. Note that with V36 it is easy to pass the
  262.              * displaymodeid as a tag (SA_DisplayID) that that is not V35 compatible.
  263.              * Also for V35 compatability this must be the first tag. */
  264.  
  265.             if (OpenA2024) 
  266.             {
  267.                 taglist[0].ti_Tag = NSTAG_EXT_VPMODE;
  268.                 taglist[0].ti_Data = VPF_A2024 | VPF_TENHZ;
  269.             } 
  270.             else 
  271.             {
  272.                 /* With V36 Intuition fully supports overscan. We'll pass the
  273.                  * Overscantype used by Workbench as a tag, and specify
  274.                  * STDSCREENWIDTH/HEIGHT in the Width and Height fields of 
  275.                  * the ExtNewScreen structure.
  276.                  */
  277.                 taglist[0].ti_Tag = SA_Overscan;
  278.                 taglist[0].ti_Data = OSCAN_TEXT;
  279.             }
  280.  
  281.             /* Indicate we want the New Look if this system is running V36 by
  282.              * specifying the SA_Pens tag and passing the pen array as data.
  283.              */
  284.             taglist[1].ti_Tag = SA_Pens;
  285.             taglist[1].ti_Data = (ULONG) dri_Pens;
  286.  
  287.  
  288.             /* End the taglist with TAG_DONE */
  289.             taglist[2].ti_Tag = TAG_DONE;
  290.  
  291.  
  292.  
  293.             /* If V36, the overscan mode will give us the right offsets */
  294.             xnewscreen.LeftEdge = 0;
  295.             xnewscreen.TopEdge = 0;
  296.  
  297.             /* Width = 1008 if A2024, 640 if < V35, STDSCREENWIDTH if V36> */
  298.             xnewscreen.Width = (OpenA2024) ? 1008 : (IsV36) ? STDSCREENWIDTH : 640;
  299.  
  300.             /* Height=1024 if A2024 & PAL, 800 if A2024 & NTSC, else STDSCREENHEIGHT */
  301.             xnewscreen.Height = (OpenA2024) ? ((IsPAL) ? 1024 : 800) : STDSCREENHEIGHT;
  302.  
  303.  
  304.             xnewscreen.Depth = 2;
  305.             xnewscreen.DetailPen = 0;
  306.             xnewscreen.BlockPen = 1;
  307.  
  308.             /* Set viewmodes to 0 if going to attempt to open in Hedley mode */
  309.             xnewscreen.ViewModes = (OpenA2024) ? 0 : HIRES | LACE;
  310.  
  311.             /* Use NS_EXTENDED to tell V35 tags are on their way */
  312.             xnewscreen.Type = CUSTOMSCREEN | NS_EXTENDED;
  313.  
  314.             /* Default font */
  315.             xnewscreen.Font = NULL;
  316.  
  317.             xnewscreen.DefaultTitle = 
  318.                      (OpenA2024) ? "VPF_A2024|VPF_TENHZ" : "HIRES|LACE";
  319.             xnewscreen.Gadgets = NULL;
  320.  
  321.             /* Pass the taglist as a V35 compatible extension. V34 will ignore this */
  322.             xnewscreen.Extension = taglist;
  323.  
  324.             if ((screen = OpenScreen(&xnewscreen)) == NULL) 
  325.             {
  326.                 /* Can't open screen. Might be V35 A2024 failure. Try with something
  327.                  * simpler.
  328.                  */
  329.                 xnewscreen.Width = (IsV36) ? STDSCREENWIDTH : 640;
  330.                 xnewscreen.Height = STDSCREENHEIGHT;
  331.                 xnewscreen.ViewModes = HIRES | LACE;
  332.                 xnewscreen.DefaultTitle = "HIRES|LACE";
  333.                 /* Get rid of A2024 tags, keep the others. */
  334.                 taglist[0].ti_Tag = SA_Overscan;
  335.                 taglist[0].ti_Data = OSCAN_TEXT;
  336.                 OpenA2024 = FALSE;
  337.                 screen = OpenScreen(&xnewscreen);
  338.                 /* If it still fails, give up */
  339.             }
  340.  
  341.             /* If screen opened, open a simple ExtNewWindow on it and wait */
  342.             if (screen) 
  343.             {
  344.                 /* Give me a zoom gadget on my window. */
  345.                 taglist[0].ti_Tag = WA_Zoom,
  346.                 taglist[0].ti_Data = (ULONG) zoomdata;
  347.                 taglist[1].ti_Tag = TAG_DONE;
  348.  
  349.                 xnewwindow.LeftEdge = 0;
  350.                 xnewwindow.TopEdge = screen->BarHeight + 1;
  351.                 xnewwindow.Width = screen->Width;
  352.                 xnewwindow.Height = screen->Height - xnewwindow.TopEdge;
  353.                 xnewwindow.DetailPen = 0;
  354.                 xnewwindow.BlockPen = 1;
  355.                 xnewwindow.IDCMPFlags = CLOSEWINDOW;
  356.                 xnewwindow.Flags =
  357.                     WINDOWSIZING | WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE |
  358.                       NW_EXTENDED | SMART_REFRESH | NOCAREREFRESH | ACTIVATE;
  359.                 xnewwindow.FirstGadget = NULL;
  360.                 xnewwindow.CheckMark = NULL;
  361.                 xnewwindow.Title = "Close to exit.";
  362.                 xnewwindow.Screen = screen;
  363.                 xnewwindow.BitMap = NULL;
  364.                 xnewwindow.MinWidth = 100;
  365.                 xnewwindow.MinHeight = 50;
  366.                 xnewwindow.MaxWidth = ~0;
  367.                 xnewwindow.MaxHeight = ~0;
  368.                 xnewwindow.Type = CUSTOMSCREEN;
  369.                 /* The window extension is completely ignored if not V36 */
  370.                 xnewwindow.Extension = taglist;
  371.  
  372.                 if (window = OpenWindow(&xnewwindow)) 
  373.                 {
  374.                     WaitPort(window->UserPort);
  375.                     while (msg = (struct IntuiMessage *)GetMsg(window->UserPort))
  376.                         ReplyMsg((struct Message *)msg);
  377.                     CloseWindow(window);
  378.                 } 
  379.  
  380.  
  381.                 else 
  382.                 {
  383.                     reqtext[0].IText = "Can't open window";
  384.                     AutoRequest(NULL, &reqtext[0], NULL, &reqtext[1],
  385.                                 NULL, GADGETUP, 320, 60);
  386.                 }
  387.                 CloseScreen(screen);
  388.             } 
  389.             else 
  390.             {
  391.                 reqtext[0].IText = "Can't open screen";
  392.                 AutoRequest(NULL, &reqtext[0], NULL, &reqtext[1],
  393.                             NULL, GADGETUP, 320, 60);
  394.             }
  395.             CloseLibrary((struct Library *) GfxBase);
  396.         }
  397.         CloseLibrary(IntuitionBase);
  398.     }
  399. }
  400.  
  401.  
  402.  
  403.  
  404.  
  405.  
  406.  
  407.  
  408. /* CheckPAL returns TRUE, if the the videomode of the specified public screen (or default videmode)
  409.  * is PAL.
  410.  * If the screenname is NULL, the default public screen will be used.
  411.  */
  412.  
  413. BOOL CheckPAL(STRPTR screenname)
  414. {
  415.     struct Screen *screen;
  416.     ULONG modeID = LORES_KEY;
  417.     struct DisplayInfo displayinfo;
  418.     BOOL IsPAL;
  419.  
  420.     if (GfxBase->LibNode.lib_Version >= 36) 
  421.     {
  422.     /*
  423.      * We got V36, so lets use the new calls to find out what
  424.      * kind of videomode the user (hopefully) prefers.
  425.      */
  426.  
  427.         if (screen = LockPubScreen(screenname)) 
  428.         {
  429.             /*
  430.              * Use graphics.library/GetVPModeID() to get the ModeID of the specified
  431.              * screen.  Will use the default public screen (Workbench most of the time)
  432.              * if NULL It is very_ unlikely that this would be invalid, heck it's
  433.              * impossible.
  434.              */
  435.             if ((modeID = GetVPModeID(&(screen->ViewPort))) != INVALID_ID) 
  436.             {
  437.                 /*
  438.                  * If the screen is in VGA mode, we can't tell whether the system is
  439.                  * PAL or NTSC. So to be fullproof we fall back to the displayinfo of 
  440.                  * the default.monitor by inquiring about just the LORES_KEY
  441.                  * displaymode if we don't know. The default.monitor reflects the
  442.                  * initial video setup of the system, thus is an alias for either
  443.                  * ntsc.monitor or pal.monitor. We only use the displaymode of the
  444.                  * specified public screen if it's display mode is PAL or NTSC and NOT
  445.                  * the default.
  446.                  */
  447.  
  448.                 if (!((modeID & MONITOR_ID_MASK) == NTSC_MONITOR_ID ||
  449.                       (modeID & MONITOR_ID_MASK) == PAL_MONITOR_ID))
  450.                     modeID = LORES_KEY;
  451.             }
  452.             UnlockPubScreen(NULL, screen);
  453.         } /* if fails modeID = LORES_KEY. Can't lock screen, 
  454.            * so fall back on default monitor. */
  455.  
  456.         if (GetDisplayInfoData(NULL, (UBYTE *) & displayinfo,
  457.             sizeof(struct DisplayInfo), DTAG_DISP, modeID)) 
  458.         {
  459.             if (displayinfo.PropertyFlags & DIPF_IS_PAL)
  460.                 IsPAL = TRUE;
  461.             else
  462.                 IsPAL = FALSE;  /* Currently the default monitor is always either
  463.                                  * PAL or NTSC.
  464.                                  */
  465.         }
  466.     } 
  467.     else /* < V36. The enhancements to the videosystem in 
  468.           * V36 cannot be better expressed than
  469.           * with the simple way to determine PAL in V34.
  470.           */
  471.         IsPAL= (GfxBase->DisplayFlags & PAL) ? TRUE : FALSE;
  472.  
  473.     return(IsPAL);
  474. }
  475.  
  476.